home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 51 / Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso / -in_the_mag- / freedos / freedos_docs / mini / emacs-mint2.txt < prev    next >
Text File  |  2000-02-08  |  27KB  |  764 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.             MINT Tutorial
  12.  
  13. This document assumes that you have loaded it into Freemacs.  You should
  14. read this document and try the examples that are given.  You may use the
  15. arrow keys to view the rest of the document.
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24. Examples
  25.  
  26. You will be shown an example program, indented one tab stop, and asked to
  27. execute it.  Rather than force you to type the example in, a MINT program
  28. has been written which executes the example directly from the text.  This
  29. MINT program is appropriately called "try-it".  Try it will execute the
  30. program that appears on the line that the cursor is on.  The result of the
  31. program, if any, will be displayed inside quotes at the top of the screen.
  32.  
  33. To try an example, position the cursor anywhere on the line containing
  34. the example and type the F2 key.  What you have just done is to execute
  35. the try it program.  Don't try to understand exactly how this works yet,
  36. just take for granted that it works.  As The Great Wizard of Oz told
  37. Dorothy, "Pay no attention to the man behind the curtain."
  38.  
  39.  
  40.  
  41. The Basics
  42.  
  43. The basic organizing principle of MINT is this:  Everything is a string,
  44. and strings are sequences of arbitrary characters.  Therefore, programs
  45. are strings and data are strings (yes, data really is plural).  The
  46. following example is a valid MINT program.  It doesn't do anything, but
  47. it's valid.
  48.  
  49.     This is a valid MINT program.
  50.  
  51. Notice that the result of executing the program is just the program
  52. itself.  This is because MINT didn't find any functions to execute.
  53.  
  54.  
  55. A Single Function
  56.  
  57. Now, for a more useful program, you need to know how MINT recognizes
  58. functions.  A MINT function to add two numbers is given below.  The two
  59. character sequence #( begins the function, ++ is the name of the
  60. function, and 5 and 7 are the arguments to the function, separated by
  61. commas.  The function adds both its arguments and returns the result as
  62. its value.  Try this program in the same manner as before, that is,
  63. place the cursor on the line and press F2.
  64.  
  65.     The sum of five and seven is #(++,5,7).
  66.  
  67. Notice that the MINT function is replaced by "12".  This is how MINT
  68. evaluates its functions.  When a function is recognized, the function is
  69. executed, and its invocation is replaced by its value.
  70.  
  71.  
  72. Multiple Functions
  73.  
  74.  
  75. Functions may be concatenated.  Try the following example.
  76.  
  77.     #(++,1,1)#(++,2,2)
  78.  
  79. You will discover that the result appears to be, and is, twenty four.
  80. This is because you concatenated the results of #(++,1,1) and #(++,2,2)
  81. to get a two and a four next to each other.  Since MINT deals with strings,
  82. a two and a four becomes twenty four.
  83.  
  84.  
  85. Functions may be nested.  Following the logic of the preceding example,
  86. nested functions are evaluated in the following manner: the function that
  87. is found first is executed first, and its invocation is replaced by its
  88. value.  The next function to be found is executed, and its invocation is
  89. replaced by its value.  Try the following example.
  90.  
  91.     #(**,3,#(++,5,7))
  92.  
  93. Notice that the value is 36, which is three multipled by twelve.
  94.  
  95.  
  96. Recognizing Functions
  97.  
  98. MINT recognizes functions by examining the input string character by
  99. character.  A # followed by a ( is taken to be the beginning of a
  100. function.  A , separates arguments from each other.  A ) causes a
  101. function to be recognized and evaluated.  Let's try the following examples.
  102.  
  103.     #(an,Hello There)
  104.  
  105. The "an" function causes its first argument to be placed on the bottom
  106. line of the screen.
  107.  
  108.     #(an,Hello There
  109.  
  110. Leaving off the closing paren causes the function to execute improperly.
  111.  
  112.     #an,Hello There)
  113.  
  114. Leaving off the opening paren causes the function to execute improperly.
  115.  
  116.     (an,Hello There)
  117.  
  118. Leaving off the sharp has a different, desirable effect.  If the MINT
  119. scanner encounters an open paren, then all the characters to the next
  120. matching close paren are skipped.  This is called protecting a string.
  121.  
  122.     (#(an,Hello There))
  123.  
  124. Notice that the "an" function is not executed.  This happens because
  125. those characters are passed over by the scanner.
  126.  
  127.     (#(**,2,#(++,5,7)))
  128.  
  129. Watch what happens when we leave off a close paren.
  130.  
  131.     (#(**,2,#(++,5,7))
  132.  
  133. We end up with the wrong thing being executed.  Watch what happens with
  134. an extra close paren.
  135.  
  136.     (#(**,2,#(++,5,7))))
  137.  
  138. Now nothing happens.  Protection works only if the parentheses are
  139. balanced!
  140.  
  141.  
  142. There are more details concerning scanning, but we'll leave those for
  143. later.
  144.  
  145.  
  146. Strings
  147.  
  148. Not unexpectedly, MINT lets you save strings under a given name.  There
  149. are no restrictions on what you name a string.  Obviously, there are
  150. certain characters that you should avoid including in a name, namely open
  151. paren, comma, and close paren, and control characters.  Let's try an example.
  152. Let's define a string called "my-test" and give it the value "this is a
  153. silly test string".  This is an example of the define string function.
  154.  
  155.     #(ds,my-test,this is a silly test string)
  156.  
  157. Wow! You just defined a string!  Big, fat, hairy deal.  Defining a string
  158. is useless until you know how to get it back, which leads us to the next
  159. example.  This is an example of the get string function.
  160.  
  161.     #(gs,my-test)
  162.  
  163. You don't always have to get the entire string.  There is a pointer
  164. associated with every string.  The gs function doesn't change it, but
  165. some of the following functions do.  You can get the string one character
  166. at a time, and the pointer is advanced by one.  Try this example several
  167. times.
  168.  
  169.     #(go,my-test)
  170.  
  171. Notice that you get the characters of "my-test" in sequence, starting at
  172. the beginning.  You might be wondering how to position the pointer back
  173. to the beginning.  Well, the following example restores the string
  174. pointer.
  175.  
  176.     #(rs,my-test)
  177.  
  178. Now that you're back at the beginning, you're ready to get several
  179. characters, using the get n characters function.  Following this
  180. example, the string pointer is positioned to the "s" of "is".
  181.  
  182.     #(ds,my-test,this is a silly test string)
  183.     #(gn,my-test,6)
  184.  
  185. You might be wondering what happens if you try to get more characters
  186. than are left following the string pointer.
  187.  
  188.     #(ds,my-test,this is a silly test string)
  189.     #(gn,my-test,1000)
  190.  
  191. You get all of them, and no more.  There are no more characters left
  192. following the string pointer.  What happens if you try to get one when
  193. there aren't any to get?
  194.  
  195.     #(ds,my-test,this is a silly test string)
  196.     #(gn,my-test,1000)
  197.     #(gn,my-test,1,gn says no more)
  198.     #(go,my-test,go also says no more)
  199.  
  200. The second argument of get one and the third argument of get n is
  201. returned if there aren't any characters left to get.
  202.  
  203. The form pointer is used by #(gs) also.
  204.  
  205.     #(ds,my-test,this is a silly test string)
  206.     #(gn,my-test,6)
  207.     #(gs,my-test)
  208.  
  209. Well, you could probably search a string for a given substring using the
  210. above functions, but it would be too much work.  A function is provided
  211. for just that purpose.  The first match function finds the first match of
  212. the given string.
  213.  
  214.     #(ds,my-test,this is a silly test string)
  215.     #(fm,my-test,silly)
  216.  
  217. The value of first match is the string up to the found string.  The
  218. string pointer, however, is positioned after the last character of the
  219. found match.  This is a nice property.  Let's use it to get the contents
  220. of "my-test" one word at a time by searching for the space between
  221. words.  First, we'll restore the string pointer.
  222.  
  223.     #(rs,my-test)
  224.     #(fm,my-test, )
  225.     #(fm,my-test, )
  226.     #(fm,my-test, )
  227.     #(fm,my-test, )
  228.     #(fm,my-test, )
  229.     #(fm,my-test, )
  230.  
  231. Aha! We didn't get "string, the last word of "my-test".  Well, of course
  232. we didn't because there isn't any space following the word "test".  We'll
  233. use this as an excuse to explain the great lie.
  234.  
  235.  
  236. The Great Lie
  237.  
  238.  
  239. I've been leading you down the primrose path.  To make things simpler,
  240. I've only told you about one type of function invocation.  There are
  241. really two types of functions, active and neutral.  The function you have
  242. been using all along is the active type of function.  After this function
  243. has been scanned, recognized, and evaluated, its result is re-scanned.  A
  244. neutral function's result is not re-scanned.  An example is in order.
  245. Let's define a string with a function in it.  Remember that we have to
  246. protect the function to keep it from being executed too soon.
  247.  
  248.     #(ds,my-test,this is a silly test string)
  249.     #(ds,my-function,(#(go,my-test)))
  250.  
  251. Let's try to retrieve the string the same way that we did earlier.
  252.  
  253.     #(gs,my-function)
  254.  
  255. The result of the function is not "#(go,my-test)" like you might imagine,
  256. but instead is the result of "#(go,my-test)".  This happens because
  257. "my-function" is re-scanned, and MINT sees the "go" function.  Let's try a
  258. neutral function.  The double sharp means neutral, not active.
  259.  
  260.     ##(gs,my-function)
  261.  
  262. Now we're getting somewhere!  What happens if we try a triple sharp?
  263. Maybe something else magical will happen?
  264.  
  265.     ###(gs,my-function)
  266.  
  267. Nope, no dice.  The extra sharp is treated as just another character,
  268. just like the period in the next example.
  269.  
  270.     .##(gs,my-function)
  271.  
  272.  
  273. Let's go back to the first match example.  What were we doing?  Oh yes,
  274. we were trying to get "my-test" one word at a time.  We ran into the
  275. difficulty of not having a blank at the end of "my-test".  We couldn't
  276. get the following example to work when the string pointer was positioned
  277. to the first character of the last word.
  278.  
  279.     #(fm,my-test, )
  280.  
  281. Well, rather than keep you in suspense, I'll give you the solution and
  282. explain it afterward.
  283.  
  284.     #(fm,my-test, ,(#(gn,my-test,100)))
  285.  
  286. Ahhhh.  Success at last.  But why?  Well, if first match doesn't find
  287. the string, it returns its third argument.  The third argument in the
  288. previous example is the "gn" function, which will get as many as it can,
  289. up to the amount specified.  This gets the last word in "my-test".
  290.  
  291. But wait...  What if I had specified that the fm be a neutral function,
  292. i.e.  I hadn't wanted to rescan the result of the first match?  Wouldn't
  293. the result be "#(gn,my-test,100)"?  Well, no, it wouldn't, because first
  294. match always rescans the third argument if that is what it returns.  And
  295. the same goes for get one #(go) and get n #(gn).
  296.  
  297.  
  298. Conditionals
  299.  
  300. So what good would a language be without conditionals?  Not much good, so
  301. several types of conditionals are supplied.  The first, equality, is
  302. demonstrated below.
  303.  
  304.     string == string: #(==,string,string,yes,no)
  305.     strin == string:  #(==,strin,string,yes,no)
  306.     string == strin: #(==,string,strin,yes,no)
  307.  
  308. Get the picture?  Those examples are simple but not so useful.  The
  309. following examples are useful but not so simple.
  310.  
  311.     #(ds,my-test,this is a silly test string)
  312.     #(==,string,string,(#(go,my-test)),(#(gn,my-test,2)))
  313.     #(==,strin,string,(#(go,my-test)),(#(gn,my-test,2)))
  314.     #(==,string,strin,(#(go,my-test)),(#(gn,my-test,2)))
  315.  
  316. Now you understand why active functions exist.  Most of your conditionals
  317. functions will be called actively.  Other conditionals functions will be
  318. explained later.  You're 75% of the way to writing real programs.
  319.  
  320.  
  321. Programs
  322.  
  323. I can see that you're just itching to write your first program.  So be
  324. it.  A program is simply a string that is re-scanned.  Let's write a
  325. really trivial program.
  326.  
  327.     #(ds,trivial,(#(==,a,b,yes,no)))
  328.     #(gs,trivial)
  329.  
  330. Oh boy! This is getting exciting!  The get string function brought
  331. trivial in, rescanned it, found the equality, evaluated it, and returned
  332. "no".  But before you get too pleased with yourself, check out the next
  333. example.
  334.  
  335.     #(trivial)
  336.  
  337. Confusion!  Where is the function name?  Well, there is no function name,
  338. and MINT recognizes that fact.  Rather than throw up its hands in disgust,
  339. MINT assumes that you want to execute "trivial" as a program, and
  340. essentially performs a get string function on "trivial".  Yes, there are
  341. some minor differences, but they will be explained in the next section.
  342.  
  343. What happens if I create a string with the same name as a primitive?  Well,
  344. you simply can't get that string using the latter method.  The primitive
  345. name list is always searched before the string name list.
  346.  
  347. Now that you know how to write programs, you'll want to pass parameters
  348. to them.
  349.  
  350.  
  351. Parameters
  352.  
  353. Programs need parameters to be at all useful.  So let's write a non
  354. trivial program, and give it parameters using the make parameter
  355. function.  The second argument to make parameter is purposefully null.
  356. Its meaning will be explained later.
  357.  
  358.     #(ds,non trivial,(#(==,a,b,yes,no)))
  359.     #(mp,non trivial,,a,b)
  360.     #(non trivial,silly,test)
  361.     #(non trivial,test,test)
  362.  
  363. The action of make parameter is to search the specified string for each
  364. of make parameter's arguments, one at a time.  Wherever a match is found,
  365. the string is removed and changed into a parameter.  The third argument
  366. becomes the first parameter, the fourth argument becomes the second
  367. parameter, etc.
  368.  
  369. The mysterious second parameter becomes the "zeroth" parameter.  When a
  370. non-function call is found, such as the "non trivial" example above, the
  371. name of the string is substituted for the "zeroth" parameter.  The use of
  372. this is explained later in the section on looping.
  373.  
  374. Rather than use single characters, such as "a" and "b" used previously,
  375. we shall use arg1, arg2, arg3, etc.  This helps arguments to stand out
  376. from the surrounding text.
  377.  
  378. The "non trivial" program returns yes if its two parameters are equal,
  379. and no otherwise.  Returning yes or no can be useful, but let's do
  380. something even more useful - return a function.  Remember that we have to
  381. protect the parameters arg2 and arg3, otherwise they both will be evaluated
  382. before the equality function is evaluated.  We also have to protect the
  383. functions that we are passing as parameters to null, otherwise they will
  384. get evaluated too soon.
  385.  
  386.     #(ds,null,(#(==,arg1,,(arg2),(arg3))))
  387.     #(mp,null,,arg1,arg2,arg3)
  388.     #(null,a,(#(an,Yes)),(#(an,No)))
  389.     #(null,,(#(an,Yes)),(#(an,No)))
  390.  
  391.  
  392.  
  393. Looping
  394.  
  395. MINT doesn't have while loops, or repeat-until loops, or for-next loops,
  396. although you could write any of them if you wish.  MINT has something
  397. which is better, called recursion.  Observe the following program, but
  398. don't try it yet!
  399.  
  400.     #(ds,recurse,(#(an,arg1)#(recurse,#(++,arg1,1))))
  401.     #(mp,recurse,,arg1)
  402.     #(recurse,1)
  403.  
  404. Notice that the program announces its parameter, and then calls itself
  405. (recurses) with one more than its argument.  There's no provision for
  406. stopping! Fortunately, MINT allows you to break out of any running
  407. program with the interrupt key (Z-100 uses S-Help, IBM-PC uses
  408. C-break).  Ok, try the program.  When you get bored, use the interrupt
  409. key to abort the program.
  410.  
  411. Clearly, we need to exercise more control over looping.  Let's rewrite
  412. "recurse" so that it stops at 100.
  413.  
  414.     #(ds,recurse,(#(an,arg1)#(==,arg1,100,,(#(recurse,#(++,arg1,1))))))
  415.     #(mp,recurse,,arg1)
  416.     #(recurse,1)
  417.  
  418. Recurse announces it argument, and checks for equality with 100.  The
  419. value of the equality is null if we've gotten to 100, otherwise it's a
  420. recursive call to itself with one more than itself.
  421.  
  422. Let's get really tricky and use the "zeroth parameter" referred to in the
  423. previous section on parameters.  Notice that we are now using the second
  424. argument to make parameter.
  425.  
  426.     #(ds,recurse,(#(an,arg1)#(==,arg1,100,,(#(SELF,#(++,arg1,1))))))
  427.     #(mp,recurse,SELF,arg1)
  428.     #(recurse,1)
  429.  
  430. When recurse is called, the SELF parameter is replaced by "recurse",
  431. so we are effectively doing the same thing as before.  By using SELF, we
  432. make it obvious that recurse is recursing, and we avoid having to
  433. explicitly name it within itself.  The advantage of this becomes apparent
  434. when you try to change the name of a function.  The fewer places that the
  435. name appears, the easier it is to change.
  436.  
  437.  
  438. Math
  439.  
  440. Math in MINT is performed on strings of digits.  A number in MINT is
  441. considered to be all the digits at the end of a string.  Try the
  442. following example.
  443.  
  444.     #(++,Boeing 707,Lockheed 40)
  445.  
  446. You can see that the two numbers are added and their sum placed at the
  447. end of the first argument.  The other four math operations  work the same
  448. way.  The only function whose meaning is not obvious is "%%", which means
  449. modulo.
  450.  
  451.  
  452.     #(--,Boeing 707,Lockheed 40)
  453.     #(**,Boeing 707,Lockheed 40)
  454.     #(//,Boeing 707,Lockheed 40)
  455.     #(%%,Boeing 707,Lockheed 40)
  456.  
  457. Numeric tests are performed using the greater than function.
  458.  
  459.     #(g?,10,20,yes,no)
  460.     #(g?,10,10,yes,no)
  461.     #(g?,20,10,yes,no)
  462.  
  463. Numeric conversions from one base to another are possible.  The following
  464. examples convert 64 decimal to other bases.
  465.  
  466.     64 decimal is #(bc,64,d,a) ASCII
  467.     64 decimal is #(bc,64,d,h) hex
  468.     64 decimal is #(bc,64,d,o) octal
  469.     64 decimal is #(bc,64,d,b) binary
  470.  
  471. The same rules for decimal numbers apply to non-decimal numbers.
  472. Converting from one base to the same base is a simple way to remove the
  473. non-digit prefix string.
  474.  
  475.     #(bc,43210,b,b)
  476.     #(bc,a9876,o,o)
  477.     #(bc,cba98,d,d)
  478.     #(bc,ihgfe,h,h)
  479.  
  480.  
  481. Base conversion provides a simple way to include a left or right paren in
  482. a program.
  483.  
  484.     ##(bc,40,d,a)
  485.     ##(bc,41,d,a)
  486.  
  487.  
  488. Odds and Ends
  489.  
  490. There are a few more functions to cover, most of which are interesting but
  491. not important enough to warrant their own section.
  492.  
  493. The halt function unconditionally exits the MINT interpreter.  Usually
  494. you want to make sure that the editor, text buffers, etc are saved before
  495. you execute this function.
  496.  
  497.     #(hl -- I don't think you really want to try this)
  498.  
  499. The number of characters function counts the number of characters in its
  500. first argument.
  501.  
  502.     #(nc,abcd)
  503.  
  504. One function exists strictly for the use of debugging Freemacs itself.  If
  505. you execute it, you will be thrown into the debugger.  This document only
  506. mentions it so that you don't run into trouble by creating a string by
  507. that name.
  508.  
  509.     #(db -- you don't really want to try this)
  510.  
  511. Ctime returns the current time and date.  If it is given an argument, then
  512. that argument is considered to be a filename.  The time and date for that
  513. filename is returned.
  514.  
  515.     #(ct)
  516.  
  517. There are several functions pertaining to strings.  The list strings
  518. function returns a list of the names of the strings that have already
  519. been defined.  Each name is followed by a copy of the second argument.
  520. Only those names that begin with the third argument are listed.  You
  521. may be surprised by the number of names listed.  Remember that the editor
  522. that you are using right now is written in MINT.
  523.  
  524.     #(ls,/)
  525.     #(ls,/,r)
  526.  
  527. Suppose we wanted to see if a string existed.  We could get the string
  528. and see if what we got wasn't null, but that fails for strings that exist
  529. and are null.  Well, the name test function comes to our rescue.
  530.  
  531.     #(n?,some silly name that doesn't exist,yes,no)
  532.     #(n?,recurse,yes,no)
  533.  
  534. The second example works because we defined recurse earlier.
  535.  
  536. Just as strings may be defined, they may be erased using erase string.
  537. Erase string may have any number of arguments.
  538.  
  539.     #(ds,foobar,this is foobar)
  540.     #(n?,foobar,y,n)
  541.     #(es,foobar)
  542.     #(n?,foobar,y,n)
  543.  
  544. Just for grins, puzzle out what the following example would do.
  545.  
  546.     #(es -- don't do it,#(ls,(,)))
  547.  
  548. Strings may be saved to and loaded from disk using save library and load
  549. library.  Remember the recurse program we wrote long ago?  Let's save it
  550. and my-test into a temporary file.  Save library may have any number of
  551. arguments.
  552.  
  553.     #(sl,mine.tmp,recurse,my-test)
  554.  
  555. If we ever want to load them back, we would use load library.  All the
  556. strings stored in the file are loaded.
  557.  
  558.     #(ll,mine.tmp)
  559.  
  560. Strings may be compared for alphabetic ordering.
  561.  
  562.     abcd = abce:    #(a?,abcd,abce,yes,no)
  563.     abcd = abcde:    #(a?,abcd,abcde,yes,no)
  564.     abce = abcd:    #(a?,abce,abcd,yes,no)
  565.     abcde = abcd:    #(a?,abcde,abcd,yes,no)
  566.     abcd = abcd:    #(a?,abcd,abcd,yes,no)
  567.  
  568. You may also wish to wait a specified time for a character to appear.
  569. The next example will wait for two seconds for a key to be pressed.  If
  570. a key was pressed, then the key will be input.
  571.  
  572.     #(it,200)
  573.     #(==,##(it,200),Timeout,no key pressed,key pressed)
  574.  
  575.  
  576. Text Buffer
  577.  
  578. The following functions deal with the text buffer.
  579.  
  580. There is a dual representation of text in the text buffer.  One is in
  581. memory, and the other is on the screen.  The function which updates this
  582. mapping is called redisplay.  You may try the following example if you
  583. wish, but since you are using Freemacs to view this text buffer, the screen
  584. already matches the memory.
  585.  
  586.     #(rd)
  587.  
  588. There are only a few functions which change the text in the buffer.  One
  589. of them is the read file function, which will be discussed later.
  590. Another is the insert string function.  Watch what happens when the next
  591. example is executed.
  592.  
  593.     #(is,Hi!)
  594.  
  595. The string "Hi!" should get inserted at the beginning of the example line.
  596.  
  597. Yet another function to modify the buffer is the delete to mark function.
  598. But before we can try it, we need to introduce marks.
  599.  
  600. Marks
  601.  
  602. To solve the problem of moving around in the buffer, the concept of the
  603. mark was created.  The word mark may be familiar because Freemacs provides
  604. a mark ring that remembers where you have been.  The Freemacs buffer marks
  605. are defined in terms of MINT marks.  A mark is a single ASCII character.
  606. There are two types of marks - system (predefined) and user (variable).
  607. The system marks are given below, and the user marks are discussed later.
  608.  
  609.     .        The point.
  610.     <        The character to the left of the point.
  611.     >        The character to the right of the point.
  612.     {        The word characters to the left of the mark.
  613.     }        The word characters to the right of the mark.
  614.     -        The non-word characters to the left of the mark.
  615.     +        The non-word characters to the right of the mark.
  616.     ^        The beginning of this line.
  617.     $        The end of this line.
  618.     *        The "split" mark.  If the current buffer is showing in
  619.             both windows, this mark is set to the point in the
  620.             other window.
  621.     [        The beginning of the file.
  622.     ]        The end of the file.
  623.  
  624. Now let's try an example.  Position the cursor to the beginning of the
  625. next example line, and try it several times.
  626.  
  627.     #(sp,>)
  628.  
  629. The cursor moves to the right once each time that you try it.
  630. Position the cursor to the end of the next example line and try it
  631. several times.
  632.  
  633.     #(sp,<)
  634.  
  635. The cursor moves to the left once each time that you try it.  Position
  636. the cursor anywhere in the next example and try it.
  637.  
  638.     #(sp,^)
  639.  
  640. The cursor always moves to the beginning of the line.   Position the
  641. cursor anywhere in the next example and try it.
  642.  
  643.     #(sp,$)
  644.  
  645. The cursor always moves to the end of the line.  We'll skip over the [
  646. and ] marks, since it's tedious to find this spot in the text again.  You
  647. can imagine how they work, however.
  648.  
  649.  
  650. Now that you know how to put text into the buffer, you need to know how
  651. to read it out of the buffer.  The read to mark function will return as
  652. its value the contents of the text buffer between the point and the
  653. specified mark.  Position the cursor to various points on the next
  654. example line and try it.  Notice that the function is a neutral call (Why?).
  655.  
  656.     ##(rm,$)
  657.     ##(rm,^)
  658.     ##(rm,>)
  659.     ##(rm,<)
  660.  
  661. Remember that I deferred talking about deleting text from the buffer? 
  662. Now you'll learn how.  The delete to mark function deletes the contents
  663. of the text buffer between the point and the specified mark.
  664.  
  665.     #(dm,$) position the cursor here >< and delete this.
  666.     delete this >< #(dm,^)
  667.     #(dm,>) position the cursor here >< and delete the left angle.
  668.     #(dm,<) position the cursor here >< and delete the right angle.
  669.  
  670.  
  671. User Marks
  672.  
  673. User marks come in two flavors, local and global.  They are called local
  674. and global because they correspond to the high level language concepts of
  675. the same name.  Global marks are always available, while only the current
  676. set of local marks are available.  A local mark is used for saving the
  677. point while you go off and do something else.  A global mark is used for
  678. saving the point to make it available to other functions.
  679.  
  680. Global marks are allocated by using a negative argument to the pm function.
  681. This also destroys all local marks.  We won't try an example right now,
  682. since the example would cause Freemacs great anguish.
  683.  
  684.     @ through Z    Global user marks.
  685.     0 through 9    Local user marks.
  686.  
  687. User marks may be set using the set mark function.  The following example
  688. sets the global mark @ to the beginning of the file.
  689.  
  690.     #(sm,@,[)
  691.  
  692. The next example sets the same mark to the point.  If the second argument
  693. is missing, it defaults to the point.
  694.  
  695.     #(sm,@)
  696.  
  697. Earlier I referred to "words".  There are two types of characters - "word"
  698. characters and non-"word" characters.  Rather than hard code a character type
  699. into a program, a table is used.  This table is simply a string that is 256
  700. characters long.  The "word" bit is bit zero, so that if the 33 character of
  701. the syntax table string (which is "!") has an odd value, then "!" is considered
  702. to be a word character.  This would be unusual.  A more usual example would
  703. cause "_" to be a word character.  The following example sets the string
  704. "Fsyntax" to be the syntax table.
  705.  
  706.     #(st,Fsyntax)
  707.  
  708.  
  709. Of course, you need to search the text buffer for strings.  There are
  710. three primitives that let you do this.  Look pattern and look regular set
  711. the pattern to be searched for, and Look actually does the searching.  To
  712. search backwards for the word search, try the following example:
  713.  
  714.     #(pm,1)            create a single user mark "0".
  715.     #(lp,search)        set the >search<ing pattern.
  716.     #(l?,.,[,0,,yes,no)    Actually look (we'll find it just above).
  717.     #(sp,0)            go back to where we found it.
  718.     #(pm)            don't forget to remove the mark.
  719.  
  720. This says to search from point to the beginning of the buffer, and set mark
  721. zero to the beginning of the matching string.  If you specify a mark as
  722. the fourth argument, it gets set to the end of the matching string.  And
  723. if the string isn't found in the buffer, the fifth argument gets returned
  724. active.
  725.  
  726. There are other parameters to the #(lp) primitive.  The MINT reference
  727. manual contains details.
  728.  
  729.  
  730.  
  731. Files
  732.  
  733. You can write a file from a buffer using the wf primitive.  All the text
  734. between the point and the mark that you specify will be written to the named
  735. file.  Position the cursor to the beginning of the example line and try it.
  736. The example will write a one line file containing itself.
  737.  
  738.     #(wf,test.tmp,$)
  739.  
  740. You can read a file into a buffer using the rf primitive.  If the result of rf
  741. is null, the file was read in successfully, otherwise the result of rf is a
  742. readable error message.  Read in the file that was written in the previous
  743. example:
  744.  
  745.     #(rf,test.tmp)
  746.  
  747. You have access to MS-DOS's directory using the ff primitive.  The following
  748. example will list all the .ED files with a bar between them:
  749.  
  750.     #(ff,*.ed,|)
  751.  
  752. You can rename MS-DOS files using the rn primitive.  Let's rename the test file
  753. that we wrote previously:
  754.  
  755.     #(rn,test.tmp,test.$$$)
  756.  
  757. Let's delete the test file with its new name:
  758.  
  759.     #(de,test.$$$)
  760.  
  761.  
  762. By now you should have a pretty good idea of how MINT operates.  At this
  763. point you should read the MINT extension writer's guide.
  764.